const MODEL_SCALE = 0.3084; //qmodel英尺转米
var _v1$2 = null; //new Vector3(0, 0, 0);
var tmplen;

function _3DObject() {
    //THREEJS 3DObject.mesh
    this.threeMesh = null;
    //location bounding box
    this.minWGS84 = null;
    this.maxWGS84 = null;
}
var CesiumTool = function (position, cesiumviewer, CesiumClass) {
    this.threeScene = null;
    this.threeCamera = null;
    this.threeRender = null;
    this.qmodel = null;
    this.cesiumPosition = position;
    this.cesiumViewer = cesiumviewer;
    this.Cesium = CesiumClass; //原Cesium类
    this.THREE = null;
    this.bindObject = []; //一个group,整个场景放入该组，然后对齐到地铁指定经纬度。
}
CesiumTool.prototype = {
    destory: function () {
        this.threeScene = null;
        this.threeCamera = null;
        this.threeRender = null;
        this.qmodel = null;
        this.cesiumViewer = null;
        this.Cesium = null;
        this.THREE = null;
        this.bindObject = null;
    },
    bindQModel: function (qmodel, threeGroup) {
        this.qmodel = qmodel;
        this.THREE = qmodel.THREE;
        this.threeScene = qmodel.get_scene();
        this.threeCamera = qmodel.get_camera();
        this.threeRender = qmodel.get_renderer();

        var _3DOB = new _3DObject();
        _3DOB.threeMesh = threeGroup;
        _3DOB.minWGS84 = this.cesiumPosition.minWGS84;
        _3DOB.maxWGS84 = this.cesiumPosition.maxWGS84;
        _3DOB.threeMesh.scale.set(MODEL_SCALE, MODEL_SCALE, MODEL_SCALE);
        this.bindObject.push(_3DOB);


        _v1$2 = new this.THREE.Vector3(0, 0, 0);
        var _this = this;
        var handler = new this.Cesium.ScreenSpaceEventHandler(this.cesiumViewer.scene.canvas);
        handler.setInputAction(function (click) {
            //   var pick = cesium.viewer.scene.pick(click.position);
            click.position.button = 0;
            click.position.clientX = click.position.x;
            click.position.clientY = click.position.y;
            _this.qmodel.imitate_screen_mouse_click(click.position);
        }, _this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },

    render: function () {
        this.renderCesium();
        this.renderThreeObj();
    },
    renderCesium: function () {
        if (this.cesiumViewer)
            this.cesiumViewer.render();
    },
    renderThreeObj: function () {
        // register QMCore.Qmjs scene with Cesium
        if (!this.cesiumViewer) return;
        if (this.bindObject.length == 0) return;
        tmplen = _v1$2.copy(this.cesiumViewer.camera.position).sub(this.bindObject[0].threeMesh.position).length();
        this.threeCamera.far = tmplen < 3000 ? 6000 : tmplen * 2;
        this.threeCamera.fov = this.Cesium.Math.toDegrees(this.cesiumViewer.camera.frustum.fovy) // ThreeJS FOV is vertical
        this.threeCamera.updateProjectionMatrix();

        var cartToVec = function (cart) {
            return { x: cart.x, y: cart.y, z: cart.z };
        };



        // Configure QMCore.Qmjs meshes to stand against globe center position up direction
        for (var id in this.bindObject) {
            this.cesiumPosition.minWGS84 = this.bindObject[id].minWGS84;
            this.cesiumPosition.maxWGS84 = this.bindObject[id].maxWGS84;
            // convert lat/long center position to Cartesian3
            var center = this.Cesium.Cartesian3.fromDegrees((this.cesiumPosition.minWGS84[0] + this.cesiumPosition.maxWGS84[0]) / 2, (this.cesiumPosition.minWGS84[1] + this.cesiumPosition.maxWGS84[1]) / 2);

            // get forward direction for orienting model
            var centerHigh = this.Cesium.Cartesian3.fromDegrees((this.cesiumPosition.minWGS84[0] + this.cesiumPosition.maxWGS84[0]) / 2, (this.cesiumPosition.minWGS84[1] + this.cesiumPosition.maxWGS84[1]) / 2, 1);

            // use direction from bottom left to top left as up-vector
            var bottomLeft = cartToVec(this.Cesium.Cartesian3.fromDegrees(this.cesiumPosition.minWGS84[0], this.cesiumPosition.minWGS84[1]));
            var topLeft = cartToVec(this.Cesium.Cartesian3.fromDegrees(this.cesiumPosition.minWGS84[0], this.cesiumPosition.maxWGS84[1]));
            var latDir = new this.THREE.Vector3().subVectors(bottomLeft, topLeft).normalize();

            // configure entity position and orientation
            this.bindObject[id].threeMesh.position.copy(center);



            this.bindObject[id].threeMesh.lookAt(centerHigh.x, centerHigh.y, centerHigh.z);
            this.bindObject[id].threeMesh.up.copy(latDir);
            if (this.cesiumPosition.gisAnglez)
                this.bindObject[id].threeMesh.rotation.z = this.cesiumPosition.gisAnglez;

        }

        // Clone Cesium Camera projection position so the
        // QMCore.Qmjs Object will appear to be at the same place as above the Cesium Globe
        this.threeCamera.matrixAutoUpdate = false;
        var cvm = this.cesiumViewer.camera.viewMatrix;
        var civm = this.cesiumViewer.camera.inverseViewMatrix;
        this.threeCamera.lookAt(new this.THREE.Vector3(0, 0, 0));

        this.threeCamera.matrixWorld.set(
            civm[0], civm[4], civm[8], civm[12],
            civm[1], civm[5], civm[9], civm[13],
            civm[2], civm[6], civm[10], civm[14],
            civm[3], civm[7], civm[11], civm[15]
        );
        this.threeCamera.matrixWorldInverse.set(
            cvm[0], cvm[4], cvm[8], cvm[12],
            cvm[1], cvm[5], cvm[9], cvm[13],
            cvm[2], cvm[6], cvm[10], cvm[14],
            cvm[3], cvm[7], cvm[11], cvm[15]
        );
        var size = this.qmodel.get_size();
        var width = size.w;
        var height = size.h;
        var aspect = width / height;
        this.threeCamera.aspect = aspect;
        this.threeCamera.updateProjectionMatrix();
        // this.markCullingRender();
        // this.doRefreshRedMarkPosition(); //todo
        this.threeRender.setSize(width, height);
        this.threeRender.clear();
        this.threeRender.render(this.threeScene, this.threeCamera);
    },
    getCesiumCamera() {
        var ca = {
            position: this.cesiumViewer.camera.positionWC.clone(),
            up: this.cesiumViewer.camera.up.clone(),
            direction: this.cesiumViewer.camera.direction.clone(),
        };
        return ca;
    },
    setCesiumCamera(homePos) {
        this.cesiumViewer.camera.flyTo({
            destination: new this.Cesium.Cartesian3(
                homePos.position.x,
                homePos.position.y,
                homePos.position.z
            ),
            duration: 3,
            orientation: {
                direction: new this.Cesium.Cartesian3(
                    homePos.direction.x,
                    homePos.direction.y,
                    homePos.direction.z
                ),
                up: new this.Cesium.Cartesian3(
                    homePos.up.x,
                    homePos.up.y,
                    homePos.up.z
                )
            }
        });
    }

}
export { CesiumTool }